library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity extern_sram_writer IS
    PORT( 
       clk                : IN std_logic;  
       
       datain             : IN unsigned(7 downto 0);  
       datain_valid       : IN std_logic;  
       module_enable	  : IN std_logic;
       
       grant              : IN std_logic;  
       grant_valid        : IN std_logic;
    
       request_out      : out std_logic;
       request_data     : out std_logic_vector(15 DOWNTO 0);
       request_addr     : out std_logic_vector(17 DOWNTO 0)
          
    );
end extern_sram_writer;



architecture Behavioral of extern_sram_writer is
  
  signal addr_buffer : unsigned(17 downto 0);
  signal data_buffer : unsigned(15 downto 0); 
  
  signal amount_words : unsigned(4 downto 0);
   
  TYPE STATE_TYPE IS (
      idle,
      read_addr2,
      read_addr3,
      read_data1,
      read_data2,
      request,
      granted
   );
 
   SIGNAL state : STATE_TYPE := idle; 
    
begin
        

 
process (clk)
begin
  if rising_edge(clk) then
  
    
    case state is
    
      when idle =>     
        if datain_valid='1' and module_enable='1' then
          addr_buffer(17 downto 16) <= datain(1 downto 0);
          amount_words <= datain(7 downto 3);
          state <= read_addr2;
        end if; 
       
      when read_addr2 =>     
        if datain_valid='1' and module_enable='1' then
          addr_buffer(15 downto 8) <= datain;
          state <= read_addr3;
        end if;
      
      when read_addr3 =>     
        if datain_valid='1' and module_enable='1' then
          addr_buffer(7 downto 0) <= datain;
          state <= read_data1;
        end if;  
      
      when read_data1 =>     
        if datain_valid='1' and module_enable='1' then
          data_buffer(15 downto 8) <= datain;
          state <= read_data2;
          amount_words <= amount_words -1;
        end if;  
       
      when read_data2 =>     
        if datain_valid='1' and module_enable='1' then
          data_buffer(7 downto 0) <= datain;
          state <= request;
        end if;  
         
      when request =>     
        if grant='1' and grant_valid='1' then
          state <= granted;
        end if;     
    
      when granted =>     
        if grant_valid='0' then
          if amount_words=0 then
            state <= idle;
          else
            state <= read_data1;
            addr_buffer <= addr_buffer +1;
          end if;
        end if;   
    
    
    end case;
    
  end if;
end process;


  request_out  <= '1' when state=request else '0';
  request_data <= std_logic_vector(data_buffer);
  request_addr <= std_logic_vector(addr_buffer);
 

end Behavioral;












